﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using SCG.SolarVengeanceEngine;
using SCG.General;
using System.IO;

namespace SCG.SolarVengeance
{
    public partial class TitlePage : BasePage
    {
        //constructors
        public TitlePage()
            : base()
        {
            InitializeComponent();
        }

        //exit button
        private void btnExit_Click(object sender, EventArgs e)
        {
            MainForm.Close();
        }

        //configure star lord button
        private void btnConfigure_Click(object sender, EventArgs e)
        {
            MainForm.ShowPage(Pages.Configure);
        }

        //new game
        private void btnNewGame_Click(object sender, EventArgs e)
        {
            MainForm.ShowPage(Pages.SetupSolo);
        }

        //grab version from assembly
        private void TitlePage_Load(object sender, EventArgs e)
        {
            lblBuild.Text = "Version " + Assembly.GetExecutingAssembly().GetName().Version;
            dlgOpen.InitialDirectory = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
        }

        //access scenarios
        public List<Scenario> Scenarios
        {
            get
            {
                return _scenarios;
            }
        }
        public Scenario FindScenario(string name)
        {
            foreach (Scenario scen in Scenarios)
                if (scen.Name == name)
                    return scen;
            return null;
        }

        //access previews
        public Dictionary<Scenario, Image> PreviewImages
        {
            get
            {
                return _previews;
            }
        }

        //access brains
        public List<Brain> Brains
        {
            get
            {
                return _brains;
            }
        }
        public Brain FindBrain(string brainName)
        {
            foreach (Brain b in Brains)
                if (b.BrainName == brainName)
                    return b;
            return null;
        }

        //load everything!
        public void LoadClasses()
        {
            //how many items to load?
            string path = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Scenarios";
            string[] scenarioFiles = Directory.GetFiles(path);
            path = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Brains";
            string[] brainFiles = Directory.GetFiles(path);
            progress.Maximum = scenarioFiles.Length + brainFiles.Length;

            //load scenarios
            SourceCodeCompiler compiler = new SourceCodeCompiler();
            foreach (string fileName in scenarioFiles)
            {
                progress.Value++;
                string scenFile = System.IO.Path.GetFileNameWithoutExtension(fileName);
                lblLoading.Text = "Loading Scenario " + scenFile;
                lblLoading.Refresh();
                string source = File.ReadAllText(fileName);
                try
                {
                    Scenario scenario = (Scenario)compiler.CompileSource(source, "Scenario", "SCG.SolarVengeanceEngine;SCG.SolarVengeance.exe");
                    if (compiler.CompilerErrors.Count > 0)
                        throw new ArgumentException(compiler.CompilerErrors[0].ErrorText);
                    _scenarios.Add(scenario);
                    Bitmap preview = ScenarioPreviewGenerator.GeneratePreview(scenario, 60, 45);
                    _previews[scenario] = preview;
                }
                catch (Exception ex)
                {
                    txtErrors.Text += "Error in Scenario " + scenFile + ": " + ex.Message + Environment.NewLine;
                    txtErrors.Visible = true;
                }
            }

            //load brains
            foreach (string fileName in brainFiles)
            {
                progress.Value++;
                string brainFile = System.IO.Path.GetFileNameWithoutExtension(fileName);
                lblLoading.Text = "Loading Brain " + brainFile;
                lblLoading.Refresh();
                string source = File.ReadAllText(fileName);
                try
                {
                    Brain brain = (Brain)compiler.CompileSource(source, "Brain", "SCG.SolarVengeanceEngine");
                    if (compiler.CompilerErrors.Count > 0)
                        throw new ArgumentException(compiler.CompilerErrors[0].ErrorText);
                    _brains.Add(brain);
                    _brainSource[brain] = source;
                }
                catch (Exception ex)
                {
                    txtErrors.Text += "Error in Brain " + brainFile + ": " + ex.Message + Environment.NewLine;
                    txtErrors.Visible = true;
                }
            }

            //hide the ugly things
            if (txtErrors.Text == "")
            {
                progress.Visible = false;
                lblLoading.Visible = false;
            }
            ShowControls(this, 1, true);
        }

        //create new brain instance
        public Brain CloneBrain(Brain brain)
        {
            string source = _brainSource[brain];
            SourceCodeCompiler compiler = new SourceCodeCompiler();
            Brain clone = (Brain)compiler.CompileSource(source, "Brain", "SCG.SolarVengeanceEngine");
            return clone;
        }

        //private members
        private List<Scenario> _scenarios = new List<Scenario>();
        private Dictionary<Scenario, Image> _previews = new Dictionary<Scenario, Image>();
        private List<Brain> _brains = new List<Brain>();
        private Dictionary<Brain, string> _brainSource = new Dictionary<Brain, string>();

        //dynamically load scenarios and brains
        private void timerLoad_Tick(object sender, EventArgs e)
        {
            timerLoad.Enabled = false;
            LoadClasses();
        }

        //start a brain duel
        private void btnBrainDuel_Click(object sender, EventArgs e)
        {
            MainForm.ShowPage(Pages.SetupDuel);
        }

        //go to lobby
        private void btnLobby_Click(object sender, EventArgs e)
        {
            MainForm.ShowPage(Pages.Lobby);
        }

        //open saved game
        private void btnOpenGame_Click(object sender, EventArgs e)
        {
            if (dlgOpen.ShowDialog(MainForm) == DialogResult.OK)
            {
                string fileName = dlgOpen.FileName;
                string s = File.ReadAllText(fileName);
                MainForm.KickoffSavedGame(s);
            }
        }

        //launch help
        private void btnHelp_Click(object sender, EventArgs e)
        {
            MainForm.ShowPage(Pages.Help);
        }
    }
}
